home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 23 / CU Amiga - Super CD-ROM 23 (June 1998).iso / CUCD / Sound / PreludeAMP / src / audio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-23  |  7.0 KB  |  335 lines

  1. /* this file is a part of amp software, (C) tomislav uzelac 1996,1997
  2. */
  3.  
  4. /* audio.c    main amp source file 
  5.  *
  6.  * Created by: tomislav uzelac    Apr 1996 
  7.  * Karl Anders Oygard added the IRIX code, 10 Mar 1997.
  8.  * Ilkka Karvinen fixed /dev/dsp initialization, 11 Mar 1997.
  9.  * Lutz Vieweg added the HP/UX code, 14 Mar 1997.
  10.  * Dan Nelson added FreeBSD modifications, 23 Mar 1997.
  11.  * Andrew Richards complete reorganisation, new features, 25 Mar 1997
  12.  * Edouard Lafargue added sajber jukebox support, 12 May 1997
  13.  */ 
  14.  
  15.  
  16. #include "amp.h"
  17.  
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20.  
  21. #ifndef __BEOS__
  22. #include <sys/uio.h>
  23. #endif
  24.  
  25. #include <sys/socket.h>
  26. #include <errno.h>
  27. #include <stdio.h>
  28. #include <fcntl.h>
  29. #include <unistd.h>
  30. #include <string.h>
  31.  
  32. #define AUDIO
  33. #include "audio.h"
  34. #include "formats.h"
  35. #include "getbits.h"
  36. #include "huffman.h"
  37. #include "layer2.h"
  38. #include "layer3.h"
  39. #include "position.h"
  40. #include "rtbuf.h"
  41. #include "transform.h"
  42. #include "controldata.h"
  43. #include "guicontrol.h"
  44.  
  45. #ifndef __BEOS__
  46. typedef int bool;
  47. #endif
  48.  
  49. void statusDisplay(struct AUDIO_HEADER *header, int frameNo)
  50. {
  51.     int minutes,seconds;
  52.  
  53.     if ((A_SHOW_CNT || A_SHOW_TIME) && !(frameNo%10))
  54.         msg("\r");
  55.     if (A_SHOW_CNT && !(frameNo%10) ) {
  56.         msg("{ %d } ",frameNo);
  57.     }
  58.     if (A_SHOW_TIME && !(frameNo%10)) {
  59.         seconds=frameNo*1152/t_sampling_frequency[header->ID][header->sampling_frequency];
  60.         minutes=seconds/60;
  61.         seconds=seconds % 60;
  62.         msg("[%d:%02d]",minutes,seconds);
  63.     }
  64.     if (A_SHOW_CNT || A_SHOW_TIME)
  65.         fflush(stderr);
  66. }
  67.  
  68. int decodeMPEG(void)
  69. {
  70. struct AUDIO_HEADER header;
  71. int cnt,g,snd_eof;
  72. uid_t my_uid = getuid();
  73.  
  74. #ifdef LINUX_REALTIME
  75.     set_realtime_priority();
  76.  
  77.     setreuid(my_uid, my_uid);
  78.  
  79.     prefetch_initial_fill();
  80. #endif /* LINUX_REALTIME */  
  81.  
  82.     initialise_globals();
  83.  
  84. #ifndef LINUX_REALTIME
  85.     if (A_FORMAT_WAVE) wav_begin();
  86. #endif /* LINUX_REALTIME */
  87.     
  88.     if ((g=gethdr(&header))!=0) {
  89.         report_header_error(g);
  90.         return -1;
  91.     }
  92.  
  93.     if (header.protection_bit==0) getcrc();
  94.  
  95. #ifdef LINUX_REALTIME
  96.     if (setup_fancy_audio(&header)!=0) {
  97.         warn("Cannot set up direct-to-DMA audio. Exiting\n");
  98.         return -1;
  99.     }
  100. #else
  101.     if (setup_audio(&header)!=0) {
  102.         warn("Cannot set up audio. Exiting\n");
  103.         return -1;
  104.     }
  105. #endif /* LINUX_REALTIME */
  106.  
  107.     
  108.     show_header(&header);
  109.  
  110.     if (header.layer==1) {
  111.         if (layer3_frame(&header,cnt)) {
  112.             warn(" error. blip.\n");
  113.             return -1;
  114.         }
  115.     } else if (header.layer==2)
  116.         if (layer2_frame(&header,cnt)) {
  117.             warn(" error. blip.\n");
  118.             return -1;
  119.         }
  120.  
  121. #ifdef LINUX_REALTIME
  122.     if (start_fancy_audio(&header)!=0) {
  123.         warn("Cannot start direct-to-DMA audio. Exiting\n");
  124.         return -1;
  125.     }
  126. #endif /* LINUX_REALTIME */
  127.  
  128.  
  129.     /*
  130.      * decoder loop **********************************
  131.      */
  132.     snd_eof=0;
  133.     cnt=0;
  134.     while (!snd_eof) {
  135.         while (!snd_eof && ready_audio()) {
  136.             if ((g=gethdr(&header))!=0) {
  137.                 report_header_error(g);
  138. #ifdef LINUX_REALTIME
  139.                 cleanup_fancy_audio();
  140. #else
  141.                 if (g==GETHDR_EOF && A_FORMAT_WAVE) wav_end(&header);
  142. #endif /* LINUX_REALTIME */
  143.                 snd_eof=1;
  144.                 break;
  145.                     }
  146.  
  147.             if (header.protection_bit==0) getcrc();
  148.  
  149.             statusDisplay(&header,cnt);    
  150.  
  151.             if (header.layer==1) {
  152.                 if (layer3_frame(&header,cnt)) {
  153.                     warn(" error. blip.\n");
  154.                     return -1;
  155.                 }
  156.             } else if (header.layer==2)
  157.                 if (layer2_frame(&header,cnt)) {
  158.                     warn(" error. blip.\n");
  159.                     return -1;
  160.                 }
  161.             cnt++;
  162.         }
  163. #ifdef LINUX_REALTIME
  164.         if (block_fancy_audio(snd_eof)!=0) {
  165.             warn("Problems with direct-to-DMA audio\n");
  166.             return -1;
  167.         }
  168. #endif
  169.     }
  170. #ifdef LINUX_REALTIME
  171.     if (stop_fancy_audio()!=0) {
  172.         warn("Cannot stop direct-to-DMA audio. Exiting\n");
  173.         return -1;
  174.     }
  175. #endif
  176.     return 0;
  177. }
  178.  
  179. int main(int argc,char **argv)
  180. {
  181. int argPos;
  182.  
  183.     argPos=args(argc,argv); /* process command line arguments */
  184.  
  185.     initialise_decoder();    /* initialise decoder */
  186.  
  187.     if (argc == 1) {     /* Start amp as a GUI backend. */
  188.         A_QUIET = TRUE;    /* TODO: change this to A_GUI_CONTROLLED */
  189. #ifndef OS_SunOS
  190.               gui_control();
  191. #endif
  192.         } else {
  193.         if (A_AUDIO_PLAY) {    /* play each specified file */
  194.             if (argPos<argc)
  195.                 for(;argPos<argc;argPos++) {
  196. #ifdef LINUX_REALTIME
  197.                                 if (geteuid() != 0) 
  198.                                         die("effective UID not root, cannot use realtime buffering\n");
  199.                 rt_play(argv[argPos]);
  200. #else /* LINUX_REALTIME */
  201.                 play(argv[argPos],0);
  202. #endif /* LINUX_REALTIME */
  203.                 }
  204.             else
  205.                 displayUsage();
  206.          } else {        /* convert the file to some format */
  207.             if ((argPos+2)==argc)
  208.                 play(argv[argPos],argv[argPos+1]);
  209.             else {
  210.                 warn("Invalid number of parameters\n");
  211.                 displayUsage();
  212.                 die("");
  213.             }
  214.     }
  215.  
  216.     msg("\nThank you for using amp!\n");
  217.     exit(0);
  218.     }
  219.   exit(0);
  220. }
  221.  
  222. /* call this once at the beginning
  223.  */
  224. void initialise_decoder(void)
  225. {
  226.     premultiply();
  227.     imdct_init();
  228.     calculate_t43();
  229. }
  230.  
  231. /* call this before each file is played
  232.  */
  233. void initialise_globals(void)
  234. {
  235.     append=data=nch=0; 
  236.         f_bdirty=TRUE;
  237.         bclean_bytes=0;
  238.  
  239.     memset(s,0,sizeof s);
  240.     memset(res,0,sizeof res);
  241. }
  242.  
  243. void report_header_error(int err)
  244. {
  245.     switch (err) {
  246.         case GETHDR_ERR: die("error reading mpeg bitstream. exiting.\n");
  247.                     break;
  248.         case GETHDR_NS : warn("this is a file in MPEG 2.5 format, which is not defined\n");
  249.                  warn("by ISO/MPEG. It is \"a special Fraunhofer format\".\n");
  250.                  warn("amp does not support this format. sorry.\n");
  251.                     break;
  252.         case GETHDR_FL1: warn("ISO/MPEG layer 1 is not supported by amp (yet).\n");
  253.                     break;
  254.         case GETHDR_FF : warn("free format bitstreams are not supported. sorry.\n");
  255.                     break;    
  256.         case GETHDR_SYN: warn("oops, we're out of sync.\n");
  257.                     break;
  258.         case GETHDR_EOF: 
  259.         default:         ; /* some stupid compilers need the semicolon */
  260.     }    
  261. }
  262.  
  263. /* TODO: there must be a check here to see if the audio device has been opened
  264.  * successfuly. This is a bitch because it requires all 6 or 7 OS-specific functions
  265.  * to be changed. Is anyone willing to do this at all???
  266.  */
  267. int setup_audio(struct AUDIO_HEADER *header)
  268. {
  269.     if (A_AUDIO_PLAY)  
  270.         if (AUDIO_BUFFER_SIZE==0)
  271.             audioOpen(t_sampling_frequency[header->ID][header->sampling_frequency],
  272.                     (header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME);
  273.         else
  274.             audioBufferOpen(t_sampling_frequency[header->ID][header->sampling_frequency],
  275.                     (header->mode!=3 && !A_DOWNMIX),A_SET_VOLUME);
  276.     return 0;
  277. }
  278.  
  279. void close_audio(void)
  280. {
  281.     if (A_AUDIO_PLAY)
  282.         if (AUDIO_BUFFER_SIZE!=0)
  283.             audioBufferClose();
  284.         else
  285.             audioClose();
  286. }
  287.  
  288. int ready_audio(void)
  289. {
  290. #ifdef LINUX_REALTIME
  291.     return ready_fancy_audio();
  292. #else
  293.     return 1;
  294. #endif
  295. }
  296.  
  297. /* TODO: add some kind of error reporting here
  298.  */
  299. void play(char *inFileStr, char *outFileStr)
  300. {
  301.     if (strcmp(inFileStr,"-")==0)
  302.         in_file=stdin;
  303.     else {
  304.         if ((in_file=fopen(inFileStr,"r"))==NULL) {
  305.             warn("Could not open file: %s\n",inFileStr);
  306.             return;
  307.         }
  308.     }
  309.     if (outFileStr) {
  310.         if (strcmp(outFileStr,"-")==0)
  311.             out_file=stdout;
  312.     else
  313.         if ((out_file=fopen(outFileStr,"w"))==NULL) {
  314.             warn("Could not write to file: %s\n",outFileStr);
  315.             return;
  316.         }
  317.         msg("Converting: %s\n",inFileStr);
  318.     }
  319.  
  320.     if (A_AUDIO_PLAY)
  321.         msg("Playing: %s\n",inFileStr);
  322.  
  323.     /*
  324.      * 
  325.      */
  326.  
  327.     decodeMPEG();
  328.     
  329.     close_audio();
  330.     fclose(in_file);
  331.     if (!A_AUDIO_PLAY) fclose(out_file);
  332.     msg("\n");
  333. }
  334.  
  335.